Dieser Beitrag wurde zuerst auf https://borisls.github.io/ veröffentlicht.

In den USA leben in den 144 bevölkerungsreichsten Kreisen ca. 50% der Einwohner. In den weiteren 2.998 Kreisen leben die weiteren 50% der Einwohner (Quelle: dataviz.com). Doch wie sieht es in Deutschland aus? Wie verteilen sich die Einwohner der 402 Kreise? Die nachfolgenden Grafiken geben Aufschluss. Datenstichtag ist der 31.12.2014 und die Daten stammen vom Bundesamt für Kartographie und Geodäsie.

Ergebnis

In Deutschland existiert keine derart große Konzentration auf einzelne Kreise wie in dem Flächenland USA. Die 93 größten Kreise haben eine Population von 49,90% der Gesamtbevölkerung. In den restlichen 309 Kreisen leben somit 50,10% der Gesamtbevölkerung. Die nachfolgenden Karten (interaktive und statisch) visualisieren die Ergebnisse.

Interaktives HTML-Widget
Ergänzende Hinweise für die Nutzung mit Smartphones oder Tablet:

Das HTML-Widget reagiert relativ träge. Damit die Informationen zu den einzelnen Kreisen eingeblendet werden können, muss der einzelne Kreis angetippt werden. Mit einem stationären Browser ist es ausreichend mit der Maus über die Kreise zu führen.

Statische Print-Version

Vorgehen zur Erstellung der Maps mit R (Choreophletenkarte)

Nachfolgend wird das Vorgehen beschrieben, wie die oben gezeigten Chorophletenkarten in R erstellt werden können. Hierbei wird für die statische Version das Package ggplot2 verwendet. Das interaktives HTML-Widget wird mit ggiraph erstellt.

Das Vorgehen untergliedert sich in folgende Teilschritte:
1. Import der Kreisgrenzen
2. Abbleitung der Verteilung der Einwohnerzahlen
3. Zusammenführung der Kreisgrenzen und Bevölkerungsdaten
4. Erstellung statischer Map mit ggplot2
5. Erstellung interaktiver Map mit ggiraph

Zu Beginn müssen die notwendigen Packages geladen werden.

library(ggplot2)
library(sp)
library(rgdal)
library(dplyr)
library(scales)
library(maptools)
library(ggiraph)
library(stringr)
library(knitr)
library(rmarkdown)

1. Schritt: Import der Kreisgrenzen

Die Kartendaten zu den Kreisgrenzen liegen als Shapefile vor. Ein Shapefile ist keine einzelne Datei, sondern besteht aus verschiedenen Dateien, die anhand eines gemeinsamen layers miteinander verbunden sind. Die hier verwendeten Kartendaten zu den Kreisgrenzen in Deutschland stammen von dem Dienstleistungszentrum des Bundes für Geoinformation und Geodäsie. Für den Import steht der readOGR-Befehl zur Verfügung.

kreise.shp <- readOGR(dsn="SpatialData2014", layer="VG250_KRS")

Das Koordinatenreferenzsystem (CRS) des Shapefiles lässt sich mit dem Befehl proj4string anzeigen und kann nach dem Einlesen verändert werden. In diesem Beispiel wird die in Deutschland häufig verwendete Projektion EPSG:4839 verwendet.

proj4string(kreise.shp)
kreise.shp <- spTransform(kreise.shp, CRS=CRS("+init=epsg:4839"))

Innerhalb des Shapefiles liegen verschiedene Identifikationsschlüssel vor. Als Identifikationsschlüssel soll der fünfstellige allgemeine Gemeindeschlüssel (AGS) verwendet werden. Dieser dient dazu

  1. die Umformung des Shapefiles in ein Dataframe mit Hilfe des Befehls fortify durchzuführen
  2. die zu visualisierenden Daten (Einwohnerzahlen) mit den Kartendaten in dem Dataframe zu verheiraten

Die Umformung des Shapefiles in ein Dataframe ist notwendig, da in dem Package ggplot2 die zu visualisierenden Daten in einem Dataframe vorgehalten werden müssen.

kreise.df <- fortify(kreise.shp, region="AGS")

Die Informationen innerhalb des Dataframes stellen einzelne Koordinaten der Kreisgrenzen dar (long und lat). Diese Koordinaten werden später mit ggplot2 und der zugehörigen Funktion geom_polygon miteinander verbunden. Durch region=AGS ist sichergestellt, dass die Polygon-Züge die jeweiligen Kreisgrenzen darstellen. Hierfür ist auch eine Reihenfolge order angegeben, in welcher Reihenfolge die Punkte miteinander verbunden werden sollen.

2. Schritt: Abbleitung der Verteilung der Einwohnerzahlen

Im zweiten Schritt müssen die flächenbezogenen Daten importiert werden. Die flächenbezogenen Daten liegen als csv-Datei vor und werden per read.csv eingelesen.

kreise.data <- read.csv(file=paste("Data2014","VG250.csv",sep="/"), 
                        header=TRUE, sep=";", dec=",", stringsAsFactors=FALSE, fileEncoding="latin1")

In dem Dataframe sind Informationen für verschiedene Ebene enthalten. Für diese Auswertung ist jedoch nur die Ebene ADE=4, d.h. die Kreiseebene relevant. Ebenfalls wird der fünfstellige Identifkationsschlüssel AGS als String transformiert und mit einer führenden 0 versehen, falls diese beim Import gelöscht worden ist.

kreise.data <- filter(kreise.data, ADE==4) %>% select(AGS, GEN, EWZ) %>% mutate(id=AGS) %>% arrange(desc(EWZ))
kreise.data$AGS <- as.character(kreise.data$AGS)
kreise.data$AGS <- ifelse(nchar(kreise.data$AGS)<5, paste0("0", kreise.data$AGS), kreise.data$AGS)

Aus den Einwohnerzahlen der einzelnen Kreise lässt sich die Gesamtbevölkerung in Deutschland mit Stand 31.12.2014 ausrechnen.

bevoelkerung.de <- sum(kreise.data$EWZ)
format(bevoelkerung.de, big.mark=" ")
## [1] "81 197 537"

Im Anschluss muss noch die Einteilung der Kreise in bevölkerungsreiche und bevölkerungsarme Kreise erfolgen. Auf dieser Basis lässt sich die Auswertung durchführen, auf welche Kreise sich die Bevölkerung konzentriert.

kreise.data$kum.EWZ <- cumsum(kreise.data$EWZ)
kreise.data$clust.EWZ <- ifelse(kreise.data$kum.EWZ > 0.5 * bevoelkerung.de, 
                                "wenige Einwohner", "viele Einwohner")
kable(kreise.data %>% group_by(clust.EWZ) %>% summarize(Kreise = n(),
                                                  Anteil = sum(EWZ)/bevoelkerung.de))
clust.EWZ Kreise Anteil
viele Einwohner 93 0.4990463
wenige Einwohner 309 0.5009537

3. Schritt: Zusammenführung der Kreisgrenzen und Bevölkerungsdaten

Für die Visualisierung von geodaten-bezogenenen Informationen auf einer Map müssen die Kartendaten (hier die Kreisgrenzen) den zu visualisierenden Daten (hier die Clustereinteilung) verheiratet werden. Hierfür wird der Befehl left_join aus dem dplyr-Package verwendet. Nachdem dies erfolgt wird zur Sicherheit die gewünschte Sortierung des Dataframe hergestellt.

plot.data <- left_join(x=kreise.df, y=kreise.data, by="id")
plot.data <- arrange(plot.data, id, order)

Das Dataframe plot.data enthält alle Informationen, die für die Choroplethenkarte notwendig sind. Nachfolgend beispielhaft dargestellt für die ersten 5 Koordinaten der Stadt Weimar mit dem allgemeinen Gemeindeschlüssel 16055.

id AGS long lat order group EWZ
16055 16055 52463 4200 502497 16055.1 63477
16055 16055 52463 4262 502498 16055.1 63477
16055 16055 52468 4324 502499 16055.1 63477
16055 16055 52614 4350 502500 16055.1 63477
16055 16055 52695 4187 502501 16055.1 63477

4. Schritt: Erstellung statischer Map mit ggplot2

Für die Erstellung der Choroplethenkarte wird ggplot2 verwendet. Die durch ggplot2 erstellen Grafiken sind nach dem Prinzip “layer by layer” aufgebaut. Das geometrische Objekt (geom), das die Kreisgrenzen beinhaltet, wird durch geom_polygon erzeugt. Die farbliche Kennzeichnung wird über die Einstellung fill gesteuert.

Für eine bessere Orientierung soll als weiterer layer die Grenzen der Bundesländer der Choroplethenkarte hinzugefügt werden. Das Vorgehen ist identisch mit dem oben beschriebenen Vorgen für die Aufbereitung des Shapefiles. Da die Bundesländergrenzen des Geodatenzentrum den territorialen Grenzen Deutschlands entsprechen und nicht den Küstenregionen folgen, wird ein Shapefile vom GADM verwendet. Die transformierten Kartendaten für die Bundesländergrenzen liegen anschließend in dem Dataframe laender.df vor und kann der Choroplethenkarte als neuer layer hinzugefügt werden.

g <- ggplot(data=plot.data) 
g <- g+ geom_polygon(aes(x=long,y=lat, group=group, fill=clust.EWZ), 
                     color="grey50", size=0.25)
g <- g + geom_path(data=laender.df, aes(x=long,y=lat, group=group), 
                   color="black", size=0.25)
g <- g + scale_fill_manual(values = c("red", "orange"), 
                           name= "Kreise", guide = guide_legend(reverse = TRUE), 
                           na.value = "grey")
g <- g + coord_equal()
g <- g + myMapTheme

Im Ergebnis ergibt sich folgende Choroplethenkarte, die die gewünschten Informationen enthält und weiter optimiert werden kann.

5. Schritt: Erstellung interaktiver Map mit ggiraph

Die Interaktive Version wird mit ggiraph erstellt. Dieses Packages ergänzt ggplot2 um interaktive geoms.

Zuerst muss eine neue Spalte in dem Dataframe ergänzt werden. Diese enthält die Informationen, die eingeblendet werden sollen, wenn der Mauszeiger über den Kreis geführt wird.

mySonderzeichen <- function(spalte){
  spalte <- str_replace(string = spalte, "Ä", "&Auml;")
  spalte <- str_replace(string = spalte, "Ö", "&Ouml;")
  spalte <- str_replace(string = spalte, "Ü", "&Uuml;")
  spalte <- str_replace(string = spalte, "ä", "&auml;")
  spalte <- str_replace(string = spalte, "ö", "&ouml;")
  spalte <- str_replace(string = spalte, "ü", "&uuml;")
  spalte <- str_replace(string = spalte, "ß", "&szlig;")
  return(spalte)
}

plot.data$tip <- paste0(
  "<b>", mySonderzeichen(plot.data$GEN), "</b> : ",
  format(plot.data$EWZ, big.mark = "."))

Da ggiraph interaktive geoms zu ggplot2 hinzufügt, ist die Syntax zur Erstellung der interaktiven Map mit der Syntax zur Erstellung der statischen Map fast identisch. Das geom geom_polygon wird durch geom_polygon_interactive ersetzt. Die neu erstellte Spalte tip enthalt die Informationen, die als tooltip erscheinen sollen. Die weiteren statischen layer bleiben unverändert.

gi <- ggplot(data=plot.data)
gi <- gi + geom_polygon_interactive(
            aes(x = long, y = lat, group = group, fill = clust.EWZ,
                tooltip = tip, data_id = id, use_jquery = TRUE), 
            color="grey50", size=0.25)
gi <- gi + geom_path(data=laender.df, aes(x=long,y=lat, group=group), 
                     color="black", size=0.25)
gi <- gi + scale_fill_manual(values = c("red", "orange"), 
                             name= "Kreise", guide = guide_legend(reverse = TRUE), 
                             na.value = "grey")
gi <- gi + coord_equal()
gi <- gi + myMapTheme

Im Ergebnis ergibt sich folgende interaktive Choroplethenkarte, die die gewünschten Informationen enthält und weiter optimiert werden kann. Der Befehl hover_css beschreibt, wie sich die Choroplethenkarte verändert, wenn der Mauszeiger über die Karte geführt wird.

ggiraph(code = {print(gi)}, hover_css = "stroke-width:2px;")